package edu.ucla.wanda.db;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.simpledb.AmazonSimpleDB;
import com.amazonaws.services.simpledb.AmazonSimpleDBClient;
import com.amazonaws.services.simpledb.model.Attribute;
import com.amazonaws.services.simpledb.model.BatchPutAttributesRequest;
import com.amazonaws.services.simpledb.model.DeleteAttributesRequest;
import com.amazonaws.services.simpledb.model.Item;
import com.amazonaws.services.simpledb.model.PutAttributesRequest;
import com.amazonaws.services.simpledb.model.ReplaceableAttribute;
import com.amazonaws.services.simpledb.model.ReplaceableItem;
import com.amazonaws.services.simpledb.model.SelectRequest;
import com.amazonaws.services.simpledb.model.SelectResult;

public class WandaSocialDbAdapter {
	// Amazon SDB object
	AmazonSimpleDB sdb;

	// information related to Facebook
	private String user_id, oauth_token, token_expires;

	// information related to the Wanda user
	private String wanda_subject_id;

	private static final String DB_DOMAIN = "WandaSocial";

	public WandaSocialDbAdapter(String user_id) throws IOException {
		try {
			sdb = new AmazonSimpleDBClient(new PropertiesCredentials(this
					.getClass().getResourceAsStream(
							"/AwsCredentials.properties")));
			// sdb.setEndpoint("https://sdb.us-west-1.amazonaws.com");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// sdb.createDomain(new CreateDomainRequest(DB_DOMAIN));

		this.user_id = user_id;

		try {
			if (!ReadFromDb()) {
				List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
				replaceableAttributes.add(new ReplaceableAttribute("user_id",
						user_id, true));
				sdb.putAttributes(new PutAttributesRequest(DB_DOMAIN, "user_"
						+ user_id, replaceableAttributes));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public String getUser_id() {
		return user_id;
	}

	/*
	 * not implemented - should call the constructor with a new user_id public
	 * void setUser_id(String user_id) { }
	 */

	public String getOauth_token() {
		return oauth_token;
	}

	public void setOauth_token(String oauth_token) throws IOException {
		if (this.oauth_token != null) {
			if (this.oauth_token.equals(oauth_token) || null == oauth_token) {
				return;
			}
		}

		this.oauth_token = oauth_token;

		// update the database representation

		// erase all attributes
		sdb.deleteAttributes(new DeleteAttributesRequest(DB_DOMAIN, "user_"
				+ user_id).withAttributes(new Attribute()
				.withName("oauth_token")));

		List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
		replaceableAttributes.add(new ReplaceableAttribute("oauth_token",
				oauth_token, true));
		sdb.putAttributes(new PutAttributesRequest(DB_DOMAIN,
				"user_" + user_id, replaceableAttributes));
	}

	public String getToken_expires() {
		return token_expires;
	}

	public void setToken_expires(String token_expires) {
		if (this.token_expires != null) {
			if (this.token_expires.equals(token_expires)
					|| null == token_expires) {
				return;
			}
		}

		this.token_expires = token_expires;

		// update the database representation

		// erase all attributes
		sdb.deleteAttributes(new DeleteAttributesRequest(DB_DOMAIN, "user_"
				+ user_id).withAttributes(new Attribute()
				.withName("token_expires")));

		List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
		replaceableAttributes.add(new ReplaceableAttribute("token_expires",
				token_expires, true));
		sdb.putAttributes(new PutAttributesRequest(DB_DOMAIN,
				"user_" + user_id, replaceableAttributes));
	}

	public String getWanda_subject_id() {
		return wanda_subject_id;
	}

	public void setWanda_subject_id(String wanda_subject_id) {
		if (this.wanda_subject_id == wanda_subject_id
				|| null == wanda_subject_id) {
			return;
		}

		this.wanda_subject_id = wanda_subject_id;

		// update the database representation

		// erase all attributes
		sdb.deleteAttributes(new DeleteAttributesRequest(DB_DOMAIN, "user_"
				+ user_id).withAttributes(new Attribute()
				.withName("wanda_subject_id")));

		// add new attributes
		List<ReplaceableAttribute> replaceableAttributes = new ArrayList<ReplaceableAttribute>();
		replaceableAttributes.add(new ReplaceableAttribute("wanda_subject_id",
				wanda_subject_id, true));
		sdb.putAttributes(new PutAttributesRequest(DB_DOMAIN,
				"user_" + user_id, replaceableAttributes));
	}

	public boolean ReadFromDb() throws IOException {
		SelectRequest selectRequest = new SelectRequest(
				"Select * from `WandaSocial` where user_id = '" + user_id + "'");
		SelectResult selectResult = sdb.select(selectRequest);

		if (0 == selectResult.getItems().size()) {
			return false;
		}

		for (Item item : selectResult.getItems()) {
			for (Attribute attribute : item.getAttributes()) {
				if ("oauth_token".equals(attribute.getName())) {
					oauth_token = attribute.getValue();
				}

				else if ("token_expires".equals(attribute.getName())) {
					token_expires = attribute.getValue();
				}

				else if ("wanda_subject_id".equals(attribute.getName())) {
					wanda_subject_id = attribute.getValue();
				}
			}
		}

		return true;
	}

	public boolean isUserProvisioned() {
		try {
			ReadFromDb();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return (null != wanda_subject_id);

	}

	public boolean WriteToDb() throws IOException {
		List<ReplaceableItem> data = new ArrayList<ReplaceableItem>();
		Vector<ReplaceableAttribute> attrs = new Vector<ReplaceableAttribute>();

		if (null == user_id || null == oauth_token || null == token_expires
				|| null == wanda_subject_id) {
			throw new IOException("incomplete item: " + this);
		}

		attrs.add(new ReplaceableAttribute("user_id", user_id, true));
		attrs.add(new ReplaceableAttribute("oauth_token", oauth_token, true));
		attrs.add(new ReplaceableAttribute("wanda_subject_id",
				wanda_subject_id, true));

		data.add(new ReplaceableItem("user_" + user_id).withAttributes(attrs));

		sdb.batchPutAttributes(new BatchPutAttributesRequest(DB_DOMAIN, data));

		return true;
	}

	// output the object as a JSON string
	public String toString() {
		String output;

		output = "{\"user\": {" + "\"user_id\": \"" + user_id + "\","
				+ "\"oauth_token\": \"" + oauth_token + "\","
				+ "\"token_expires\": \"" + token_expires + "\","
				+ "\"wanda_subject_id\": \"" + wanda_subject_id + "\" } }";

		return output;
	}

	public void deleteUser() {
		sdb.deleteAttributes(new DeleteAttributesRequest(DB_DOMAIN, "user_"
				+ user_id));
		user_id = wanda_subject_id = oauth_token = token_expires = null;
	}
}
